/**
************************************************************
* @file         main.c
* @brief        MCU版 入口文件
* @author       Gizwits
* @date         2016-09-05
* @version      V03010101
* @copyright    Gizwits
* 
* @note         机智云.只为智能硬件而生
*               Gizwits Smart Cloud  for Smart Products
*               链接|增值ֵ|开放|中立|安全|自有|自由|生态
*               www.gizwits.com
*
***********************************************************/

#include <string.h>
#include "delay.h"
#include "Hal_key/hal_key.h"
#include "Hal_Usart/hal_uart.h"
#include "Hal_Watchdog/hal_watchdog.h"
#include "gizwits_protocol.h"
#include "gizwits_protocol.h"
#include "Hal_rtc/rtc.h"
#include "Hal_Flash/stmflash.h"
#include "Hal_led/Hal_led.h"
#include "gizwits_product.h"
#include "Hal_temp_hum/hal_temp_hum.h"
#include "TIM_Calc/TIM_Calc.h"
#include "Hal_Remote/Hal_remote.h"
#define SAVEFLASH 1
/** 用户区当前设备状态结构体*/
dataPoint_t currentDataPoint;

extern _calendar_obj calendar;	//日历结构体
extern volatile CalendarClock_t CalendarClock;//日历时钟
extern volatile CountDowntime_t CountDowntime;//预约时间
extern gizwitsProtocol_t gizwitsProtocol;
volatile gizwitsReport_t reportData;//结构体 设备存储的状态
devStatus_t *devStatus;  
gizwitsIssued_t *issuedData;
dataPoint_t *dataPoints;
extern u8 irctl;
 u8 HEARTBEATFFlag;//心跳标志，超时就重启
/**@name 按键相关定义 
* @{
*/
#define GPIO_KEY_NUM 2                                  ///< 定义按键成员总数
keyTypedef_t singleKey[GPIO_KEY_NUM];                   ///< 定义单个按键成员数组指针
keysTypedef_t keys;                                     ///< 定义总的按键模块结构体指针
/**@} */

/**
* 用户初始化函数

* 在该函数中完成了外设驱动初始化以及用户相关数据的初始
* @param none
* @return none
* @note 开发者可在此函数内添加新的驱动初始及状态初始化
*/
void userInit(void)
{
	    delayInit(72);

    uartxInit();        //printf打印串口初始化
		ledGpioInit();
	  dht11Init();
		TIM_Calc_Init();
		RTC_Init();
		RedInit();
    watchdogInit(2);    //看门狗复位时间2s
    memset((uint8_t*)&currentDataPoint, 0, sizeof(dataPoint_t));
}

/**
* 用户数据获取

* 此处需要用户实现除可写数据点之外所有传感器数据的采集,可自行定义采集频率和设计数据过滤算法
* @param none
* @return none
*/

void userHandle(void)
{
	    /*
    currentDataPoint.valueTemperature = ;//Add Sensor Data Collection
    currentDataPoint.valueHumidity = ;//Add Sensor Data Collection
    currentDataPoint.valuevalue_I = ;//Add Sensor Data Collection
    currentDataPoint.valuevalue_V = ;//Add Sensor Data Collection
    currentDataPoint.valuevalue_P = ;//Add Sensor Data Collection
    currentDataPoint.valuePower_Consumption = ;//Add Sensor Data Collection
    currentDataPoint.valueAlert_1 = ;//Add Sensor Data Collection
    currentDataPoint.valueAlert_2 = ;//Add Sensor Data Collection
    currentDataPoint.valueFault_LED = ;//Add Sensor Data Collection
    currentDataPoint.valueFault_TemHum = ;//Add Sensor Data Collection
    currentDataPoint.valueFault_V = ;//Add Sensor Data Collection
    currentDataPoint.valueFault_I = ;//Add Sensor Data Collection
    currentDataPoint.valueFault_P = ;//Add Sensor Data Collection

    */
	    uint8_t ret  = 0;
	    static uint32_t thLastTimers = 0;//保存最后进入时间，与系统时间之差为进入处理间隔
	static uint32_t thLastTimer=0;
//    float temp;
	static uint8_t TI_flag=0;
	static uint32_t irchecktimes=0;
		static uint32_t uptimeLastTimer = 0;//保存最后进入时间，与系统时间之差为进入处理间隔
		static uint32_t HEARTBEATLastTimer=0;//WIFI心跳包检测，超过多少分钟就重启
//		if(CountDowntime.Calendar_min_flag)//如果启用了预约功能
//			{
//				CountDowntime.Calendar_min_flag=0;
//				CountDowntime.CountDown_Minute_time--;
//		//		printf("%d\r\n",CountDowntime.CountDown_Minute_time);
//				if(CountDowntime.CountDown_Minute_time<=0)//减到0 
//				{
//						TIM_Cmd(TIM4,DISABLE);  //失能TIMx外设
//						CountDowntime.Calendar_time_min = 0;
//					  CountDowntime.Calendar_time_sec = 0;
//						CountDowntime.CountDown_Minute_time = 0;
//						currentDataPoint.valueCountDown_OnOff=0;
//					if(reportData.devStatus.wBitBuf[0] == 0x01)//如果当前是开的就关闭插座
//					{
//						ledOff(LED4);//插座开关指示灯 关
//						ledOff(LED3);//PB12插座开关   关闭
//						//ledRgbControl(0,0,0);        
//						reportData.devStatus.wBitBuf[0]  = 0x00;//保存关的状态	
//						CalendarClock.Calendar_OnOff  = 0x00;//保存关的状态						
//					}
//					else if(reportData.devStatus.wBitBuf[0]  == 0x00)//如果当前是关的就打开插座
//					{
//						ledOn(LED4);//插座开关指示灯 开
//						ledOn(LED3);//PB12插座开关   打开
//						//ledRgbControl(254,0,0);       
//						reportData.devStatus.wBitBuf[0]  = 0x01;//保存开的状态
//						CalendarClock.Calendar_OnOff  = 0x01; //保存开的状态
//					}	
//					reportData.devStatus.valueCountDown_Minute = 0x00;//保存关的状态
//					#ifdef  SAVEFLASH
//					STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//保存到FLASH里
//					#endif
//					printf("Evt: CountDown_Minute_time= %d Executed\r\n",CountDowntime.CountDown_Minute_time);
//				}
//				//把当前还剩余的时间返回给APP
//				//reportData.devStatus.valueCountDown_Minute=CountDowntime.CountDown_Minute_time;
//				currentDataPoint.valueCountDown_Minute=CountDowntime.CountDown_Minute_time;
//			//dataPoints->valueCountDown_Minute = gizX2Y(COUNTDOWN_MINUTE_RATIO,  COUNTDOWN_MINUTE_ADDITION, gizProtocolExchangeBytes(CountDowntime.CountDown_Minute_time));
//			printf("%d\r\n",currentDataPoint.valueCountDown_Minute*60);
//			}
			//-----------------------------}
		//-----------------------------{
//		printf("%d\r\n",gizGetTimerCount());
		if((gizGetTimerCount()-irchecktimes) > REPORT_IRTIME_MAX) //查询开关定时到了没有
				{
					if(irctl==0x01)
					{
							if(reportData.devStatus.wBitBuf[0] == 0x01)//如果当前是开的就关闭插座
							{
							//			ledOff(LED4);//插座开关指示灯 关
							ledOff(LED4);//插座开关指示灯 关
							ledOff(LED3);//PB12插座开关   关闭    
							reportData.devStatus.wBitBuf[0] = 0x00;//保存关的状态
							currentDataPoint.valueLED_OnOff=0x00;
							//			CalendarClock.Calendar_OnOff  = 0x00;//保存关的状态
							}
							else if(reportData.devStatus.wBitBuf[0]  == 0x00)//如果当前是关的就打开插座
							{
							//			ledOn(LED4);//插座开关指示灯 开
							ledOn(LED4);//插座开关指示灯 开
							ledOn(LED3);//PB12插座开关	 打开

							reportData.devStatus.wBitBuf[0] = 0x01;//保存开的状态
							currentDataPoint.valueLED_OnOff=0x01;
							//CalendarClock.Calendar_OnOff  = 0x01; //保存开的状态
							}
							irctl=0;
				}
			}		
			if((gizGetTimerCount()-thLastTimers) > REPORT_TIME_MAX) //查询开关定时到了没有
				{
				//	printf("6S read!!\r\n");
					if(TI_flag==0x00){
						GPIO_SetBits(GPIOA,GPIO_Pin_5);
						TI_flag=1;
					}
					if(TI_flag==0x01)
						GPIO_ResetBits(GPIOA,GPIO_Pin_5);
//					if(CalendarClock.Calendar_onoffflag == 0x01)//如果打开了定时标志位才进入
//					{
//						GIZWITS_LOG("2\r\n");
//						if((CalendarClock.Calendar_Week & ( 1<<(calendar.week-1)))==( 1<<(calendar.week-1)))//先判断星期是否是设置的。然后判断小时，分钟
						if((CalendarClock.Calendar_Offflag==0x01) ||( CalendarClock.Calendar_Onflag==0x01))
						{
					//	GIZWITS_LOG("3\r\n");
							//printf("nowtime=%d,setontime=%d,setofftime=%d\r\n",(calendar.hour*60+calendar.min),CalendarClock.Calendar_Time_On_Minute,CalendarClock.Calendar_Time_Off_Minute);
							if(CalendarClock.Calendar_Time_On_Minute !=CalendarClock.Calendar_Time_Off_Minute)//如果定时开与定时关时间不同才能进入控制
							{
							//	GIZWITS_LOG("4\r\n");
								if(CalendarClock.Calendar_Time_On_Minute==((calendar.hour*60)+calendar.min))//如果设置的小时数与现在的小时数相同 16进制表示
								{
									//ledRgbControl(254,0,0);        //开插座 
									ledOn(LED4);//插座开关指示灯 开
									ledOn(LED3);//PB12插座开关	 打开
									currentDataPoint.valueLED_OnOff = 0x01;//保存开的状态
									CalendarClock.Calendar_OnOff  = 0x01; //保存开的状态
									if(CalendarClock.Calendar_OnRepeat==0x00){
										currentDataPoint.valueTime_On_Minute=0;
										currentDataPoint.valueTime_On=0;
									}
									GIZWITS_LOG("Calendar_Time_On_Minute= %d Executed\r\n",CalendarClock.Calendar_Time_On_Minute);
									
								}
								else if(CalendarClock.Calendar_Time_Off_Minute==((calendar.hour*60)+calendar.min))
								{
									ledOff(LED4);//插座开关指示灯 关
									ledOff(LED3);//PB12插座开关   关闭
									//ledRgbControl(0,0,0);        
//									reportData.devStatus.wBitBuf[0] = 0x00;//保存八ԧڄ状态 
									currentDataPoint.valueLED_OnOff=0x00;
									CalendarClock.Calendar_OnOff  = 0x00;//保存关的状态
									if(CalendarClock.Calendar_OffRepeat==0x00){
										currentDataPoint.valueTime_Off_Minute=0;
										currentDataPoint.valueTime_Off=0;
									}
								
									GIZWITS_LOG("Calendar_Time_Off_Minute= %d Executed\r\n",CalendarClock.Calendar_Time_Off_Minute);
								}
					#ifdef  SAVEFLASH
					STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//保存到FLASH里
					#endif
						}
					}
//			}
					thLastTimers = gizGetTimerCount();
	}

//			 //-----------------------------}
				if((gizGetTimerCount()-uptimeLastTimer) > UPTIME_TIME_MAX) //0.5秒进入查询查询开关定时到了没有
		{
	
					//{ADC查询Vout = 2.5 + 0.1*Ip  没有电流在中间位置2.5V 正向电流 4.5V/20A   反向电流0.5V/20A
				//-----------------------------}

		//-----------------------------{
		uptimeLastTimer = gizGetTimerCount();
		}
				//-----------------------------{		//-----------------------------{		//-----------------------------{		//-----------------------------{
		    if((gizGetTimerCount()-thLastTimer) > SAMPLING_TIME_MAX) 
    {
        ret = dht11Read((uint8_t *)&currentDataPoint.valueTemperature, (uint8_t *)&currentDataPoint.valueHumidity);
//			printf("2S read!!\r\n");
        if(ret != 0)
        {
            printf("Failed to read DHT11\r\n");
        }
				if(currentDataPoint.valueLED_OnOff!=0)
				frq_read((uint32_t *)&currentDataPoint.valuevalue_V,(uint32_t *)&currentDataPoint.valuevalue_I,(uint32_t *)&currentDataPoint.valuevalue_P);
				if(currentDataPoint.valueLED_OnOff==0)
					currentDataPoint.valuevalue_I=0;
        thLastTimer = gizGetTimerCount();
    }
				//-----------------------------{		//-----------------------------{		//-----------------------------{		//-----------------------------{
		if((gizGetTimerCount()-HEARTBEATLastTimer) > HEARTBEAT_TIME_MAX)//180秒进入一次
		{
			if(HEARTBEATFFlag==1)
			{
				 GIZWITS_LOG("Info: 180sec HEARTBEAT_TIME_MAX wifi RESET\r\n");
				 
				 ledOff(LED2);//PB14 LEDG 绿灯网络指示灯
				 delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
				 delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
				 delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
				 delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
		
			}
			HEARTBEATFFlag=1;
			HEARTBEATLastTimer=gizGetTimerCount();//保存最后进入时间
		}
}

///**
//* key1按键短按处理
//* @param none
//* @return none
//*/
//void key1ShortPress(void)
//{
//    printf("KEY1 PRESS ,Production Mode\n");
//    gizwitsSetMode(WIFI_PRODUCTION_TEST);
//}

///**
//* key1按键长按处理
//* @param none
//* @return none
//*/
//void key1LongPress(void)
//{
//    printf("KEY1 PRESS LONG ,Wifi Reset\n");
//    gizwitsSetMode(WIFI_RESET_MODE);

//}

///**
//* key2按键短按处理
//* @param none
//* @return none
//*/
void key2ShortPress(void)
{
    printf("KEY2 PRESS ,Soft AP mode\n");
//    gizwitsSetMode(WIFI_SOFTAP_MODE);
		if(reportData.devStatus.wBitBuf[0] == 0x01)//如果当前是开的就关闭插座
		{
//			ledOff(LED4);//插座开关指示灯 关
			ledOff(LED4);//插座开关指示灯 关
			ledOff(LED3);//PB12插座开关   关闭
		       
			reportData.devStatus.wBitBuf[0] = 0x00;//保存关的状态
			currentDataPoint.valueLED_OnOff=0x00;
//			CalendarClock.Calendar_OnOff  = 0x00;//保存关的状态
		}
		else if(reportData.devStatus.wBitBuf[0]  == 0x00)//如果当前是关的就打开插座
		{
//			ledOn(LED4);//插座开关指示灯 开
			ledOn(LED4);//插座开关指示灯 开
			ledOn(LED3);//PB12插座开关	 打开
		
				reportData.devStatus.wBitBuf[0] = 0x01;//保存开的状态
			currentDataPoint.valueLED_OnOff=0x01;
				//CalendarClock.Calendar_OnOff  = 0x01; //保存开的状态
		}
}

/**
* key2按键长按处理
* @param none
* @return none
*/
void key2LongPress(void)
{
    //AirLink mode
    printf("KEY2 PRESS LONG ,AirLink mode\n");
	  ledOn(LED2);//PB14 进入AirLink模式
    gizwitsSetMode(WIFI_AIRLINK_MODE);
}

/**
* 按键初始化
* @param none
* @return none
*/
void keyInit(void)
{
//    singleKey[0] = keyInitOne(RCC_APB2Periph_GPIOB, GPIOB, GPIO_Pin_10, key1ShortPress, key1LongPress);
    singleKey[0] = keyInitOne(RCC_APB2Periph_GPIOA, GPIOA, GPIO_Pin_8, key2ShortPress, key2LongPress);
    keys.singleKey = (keyTypedef_t *)&singleKey;
    keyParaInit(&keys); 
}

/**
* @brief程序入口函数

* 在该函数中完成用户相关的初始化,及主逻辑循环
* @param none
* @return none
*/
int main(void)
{
    SystemInit();
    
    userInit();
    keyInit();
		ledOn(LED1); //PB15LEDR 红灯 打开
    timerInit();
    uartInit();

    gizwitsInit();
	printf("get time api\r\n");
//    gizwitsGetTime();//调用获取网络时间API
	#ifdef  SAVEFLASH
STMFLASH_Read(FLASH_SAVE_ADDR,( u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//从FLASH读取保存的数据
	if((currentDataPoint.valueTime_On>=1)||(currentDataPoint.valueTime_Off>=1)||(currentDataPoint.valueTime_On_Minute>1440)||(currentDataPoint.valueTime_Off_Minute>1440)||(CalendarClock.Calendar_Week>127))
	{
			printf("Calendar_OnOff          1=%d \r\n",CalendarClock.Calendar_OnOff);
	    printf("Calendar_Onflag      2=%d \r\n",CalendarClock.Calendar_Onflag);
		  printf("Calendar_Offflag           3=%d \r\n",CalendarClock.Calendar_Offflag);
			printf("Calendar_Time_On_Minute 4=%d \r\n",CalendarClock.Calendar_Time_On_Minute);
			printf("Calendar_Time_Off_Minute5=%d \r\n",CalendarClock.Calendar_Time_Off_Minute);
			CalendarClock.Calendar_onoffflag=0;
			CalendarClock.Calendar_Week=0;
			CalendarClock.Calendar_Time_On_Minute=0;
			CalendarClock.Calendar_Time_Off_Minute=0;
			#ifdef  SAVEFLASH
			STMFLASH_Write(FLASH_SAVE_ADDR,(u16*)&CalendarClock,sizeof(CalendarClock_t)+1);//保存到FLASH里
			#endif	
	}

STMFLASH_Read(FLASH_SAVE_ADDR,( u16*)&CalendarClock,sizeof(CalendarClock_t)+1);
#endif
		currentDataPoint.valueLED_OnOff      =CalendarClock.Calendar_OnOff;
//		currentDataPoint.valueTime_OnOff=CalendarClock.Calendar_onoffflag;
//		reportData.devStatus.valueWeek_Repeat=CalendarClock.Calendar_Week;
	currentDataPoint.valueTime_On=CalendarClock.Calendar_Onflag;
		currentDataPoint.valueTime_Off=CalendarClock.Calendar_Offflag;
		reportData.devStatus.valueTime_On_Minute    =gizProtocolExchangeBytes(CalendarClock.Calendar_Time_On_Minute);//转回去
		reportData.devStatus.valueTime_Off_Minute   =gizProtocolExchangeBytes(CalendarClock.Calendar_Time_Off_Minute);
			printf("Calendar_OnOff          1=%d \r\n",CalendarClock.Calendar_OnOff);
	    printf("Calendar_Onflag      2=%d \r\n",CalendarClock.Calendar_Onflag);
		  printf("Calendar_Offflag           3=%d \r\n",CalendarClock.Calendar_Offflag);
			printf("Calendar_Time_On_Minute 4=%d \r\n",CalendarClock.Calendar_Time_On_Minute);
			printf("Calendar_Time_Off_Minute5=%d \r\n",CalendarClock.Calendar_Time_Off_Minute);
	
	
	if(reportData.devStatus.wBitBuf[0] == 0x01)//如果当前是开的就关闭插座
		{
//			ledOff(LED4);//插座开关指示灯 关
			ledOff(LED4);//插座开关指示灯 关
			ledOff(LED3);//PB12插座开关   关闭    
			reportData.devStatus.wBitBuf[0] = 0x00;//保存关的状态
			currentDataPoint.valueLED_OnOff=0x00;
//			CalendarClock.Calendar_OnOff  = 0x00;//保存关的状态
		}
		else if(reportData.devStatus.wBitBuf[0]  == 0x00)//如果当前是关的就打开插座
		{
//			ledOn(LED4);//插座开关指示灯 开
			ledOn(LED4);//插座开关指示灯 开
			ledOn(LED3);//PB12插座开关	 打开
  
				reportData.devStatus.wBitBuf[0] = 0x01;//保存开的状态
			currentDataPoint.valueLED_OnOff=0x01;
				//CalendarClock.Calendar_OnOff  = 0x01; //保存开的状态
		}
		delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
		delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
		delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();delayMs(1000);watchdogFeed();//喂狗
		ledOn(ESPONOFF);//ESPwifi电源打开
		ledOff(LED1);//PB15LEDR 红灯 关闭初始化完成

    printf("MCU Init Success \n");
    while(1)
    {
        watchdogFeed();
        redRead();
        userHandle();
        
        gizwitsHandle((dataPoint_t *)&currentDataPoint);
    }
}
